/**
 * Service Worker 管理器
 * @description 提供Service Worker注册、更新、缓存管理、推送通知等功能
 * @author 系统开发团队
 * @version 1.0.0
 */

// ==================== Service Worker管理器类 ====================

/**
 * Service Worker管理器类
 * @description 管理Service Worker的生命周期、缓存、推送通知等功能
 */
class ServiceWorkerManager {
  /** Service Worker注册对象 */
  private registration: ServiceWorkerRegistration | null = null
  /** 浏览器是否支持Service Worker */
  private isSupported = 'serviceWorker' in navigator

  /**
   * 注册Service Worker
   * @description 注册Service Worker并设置更新监听器
   * @returns {Promise<boolean>} 注册是否成功
   * @example
   * const success = await serviceWorkerManager.register()
   * if (success) {
   *   console.log('Service Worker注册成功')
   * }
   */
  async register(): Promise<boolean> {
    if (!this.isSupported) {
      console.warn('Service Worker not supported')
      return false
    }

    try {
      // 注册Service Worker
      this.registration = await navigator.serviceWorker.register('/sw.js', {
        scope: '/'
      })

      console.log('Service Worker registered:', this.registration)

      // 监听Service Worker更新
      this.registration.addEventListener('updatefound', () => {
        const newWorker = this.registration!.installing
        if (newWorker) {
          newWorker.addEventListener('statechange', () => {
            if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
              this.showUpdateNotification()
            }
          })
        }
      })

      // 监听控制器变化（更新完成）
      navigator.serviceWorker.addEventListener('controllerchange', () => {
        console.log('Service Worker controller changed')
        window.location.reload()
      })

      return true
    } catch (error) {
      console.error('Service Worker registration failed:', error)
      return false
    }
  }

  /**
   * 显示更新通知
   * @description 当有新版本可用时显示更新提示
   * @private
   */
  private showUpdateNotification(): void {
    if (confirm('有新版本可用，是否立即更新？')) {
      this.update()
    }
  }

  /**
   * 更新Service Worker
   * @description 激活等待中的Service Worker更新
   * @returns {Promise<void>}
   * @example
   * await serviceWorkerManager.update()
   */
  async update(): Promise<void> {
    if (this.registration && this.registration.waiting) {
      this.registration.waiting.postMessage({ type: 'SKIP_WAITING' })
    }
  }

  /**
   * 获取缓存信息
   * @description 通过消息通道获取Service Worker的缓存信息
   * @returns {Promise<any>} 缓存信息对象
   * @example
   * const cacheInfo = await serviceWorkerManager.getCacheInfo()
   * console.log('缓存信息:', cacheInfo)
   */
  async getCacheInfo(): Promise<any> {
    if (!this.registration) {
      return null
    }

    return new Promise((resolve) => {
      const channel = new MessageChannel()
      
      channel.port1.onmessage = (event) => {
        if (event.data.type === 'CACHE_INFO') {
          resolve(event.data)
        }
      }

      this.registration!.active?.postMessage(
        { type: 'GET_CACHE_INFO' },
        [channel.port2]
      )
    })
  }

  /**
   * 清除所有缓存
   * @description 清除所有Service Worker相关的缓存
   * @returns {Promise<void>}
   * @example
   * await serviceWorkerManager.clearAllCaches()
   * console.log('所有缓存已清除')
   */
  async clearAllCaches(): Promise<void> {
    if (!this.isSupported) {
      return
    }

    try {
      const cacheNames = await caches.keys()
      await Promise.all(
        cacheNames.map(cacheName => caches.delete(cacheName))
      )
      console.log('All caches cleared')
    } catch (error) {
      console.error('Failed to clear caches:', error)
    }
  }

  /**
   * 请求推送通知权限
   * @description 请求用户授权推送通知权限
   * @returns {Promise<NotificationPermission>} 通知权限状态
   * @example
   * const permission = await serviceWorkerManager.requestNotificationPermission()
   * if (permission === 'granted') {
   *   console.log('推送通知权限已授权')
   * }
   */
  async requestNotificationPermission(): Promise<NotificationPermission> {
    if (!this.isSupported || !('Notification' in window)) {
      return 'denied'
    }

    if (Notification.permission === 'default') {
      return await Notification.requestPermission()
    }

    return Notification.permission
  }

  /**
   * 发送推送通知
   * @description 发送本地推送通知
   * @param {string} title 通知标题
   * @param {NotificationOptions} options 通知选项
   * @returns {Promise<void>}
   * @example
   * await serviceWorkerManager.sendNotification('新消息', {
   *   body: '您有一条新消息',
   *   icon: '/icon.png'
   * })
   */
  async sendNotification(title: string, options?: NotificationOptions): Promise<void> {
    if (Notification.permission === 'granted' && this.registration) {
      await this.registration.showNotification(title, options)
    }
  }

  /**
   * 检查网络状态
   * @description 检查当前网络连接状态
   * @returns {boolean} 是否在线
   * @example
   * const isOnline = serviceWorkerManager.isOnline()
   * console.log('网络状态:', isOnline ? '在线' : '离线')
   */
  isOnline(): boolean {
    return navigator.onLine
  }

  /**
   * 监听网络状态变化
   * @description 监听网络连接状态的变化
   * @param {Function} callback 状态变化回调函数
   * @example
   * serviceWorkerManager.onNetworkChange((isOnline) => {
   *   console.log('网络状态变化:', isOnline ? '在线' : '离线')
   * })
   */
  onNetworkChange(callback: (isOnline: boolean) => void): void {
    window.addEventListener('online', () => callback(true))
    window.addEventListener('offline', () => callback(false))
  }

  /**
   * 获取Service Worker状态
   * @description 获取Service Worker的完整状态信息
   * @returns {ServiceWorkerStatus} 状态信息对象
   * @example
   * const status = serviceWorkerManager.getStatus()
   * console.log('Service Worker状态:', status)
   */
  getStatus(): ServiceWorkerStatus {
    return {
      isSupported: this.isSupported,
      isRegistered: !!this.registration,
      isOnline: this.isOnline(),
      permission: Notification.permission
    }
  }
}

// ==================== 实例和类型定义 ====================

/** Service Worker管理器单例实例 */
export const serviceWorkerManager = new ServiceWorkerManager()

/**
 * 缓存信息接口
 * @description 定义缓存信息的数据结构
 */
export interface CacheInfo {
  /** 缓存类型 */
  type: string
  /** 缓存名称列表 */
  cacheNames: string[]
}

/**
 * Service Worker状态接口
 * @description 定义Service Worker状态信息的数据结构
 */
export interface ServiceWorkerStatus {
  /** 是否支持Service Worker */
  isSupported: boolean
  /** 是否已注册 */
  isRegistered: boolean
  /** 是否在线 */
  isOnline: boolean
  /** 通知权限状态 */
  permission: NotificationPermission
} 